import java.util.*;

public class Unicorns {

	static int k;
	static int n;
	static int total;
	static int m;
	static int eating;
	static Barrier Br = new Barrier();
	static Semaphore mutex = new Semaphore(1);
	static Semaphore Bmutex = new Semaphore(1);
	static Semaphore notifier = new Semaphore(0);
	static Semaphore mother = new Semaphore(0);
	static Semaphore in = new Semaphore(1);
	static Mother Mot = new Mother();
	static userinterface ui=new userinterface();

	static class Semaphore {
		int val;
		int waiting;

		public Semaphore(int v) {
			val = v;
			waiting = 0;
		}

		public synchronized void up() {
			if (waiting > 0) {
				waiting--;
				notify();
			} else
				val++;
		}

		public synchronized void down() {
			if (val == 0) {
				waiting++;
				go_to_sleep();
			} else
				val--;
		}

		public void go_to_sleep() {
			try {
				wait();
			} catch (InterruptedException IE) {
				IE.printStackTrace();
			}
		}
	}

	static class Barrier {
		int wait;
		int waitSec;

		public Barrier() {
			waitSec = (int) (Math.random() * 10000);
			wait = 0;
		}

		public synchronized int play() {
			int ret;
			Bmutex.down();
			wait++;
			if (wait < 3) {
				Bmutex.up();
				ret = waitSec;
				go_to_sleep();
			} else {
				ret = waitSec;
				wait = 0;
				waitSec = (int) (Math.random() * 10000);
				notifyAll();
				Bmutex.up();
			}
			return ret;
		}

		public void go_to_sleep() {
			try {
				wait();
			} catch (InterruptedException IE) {
				IE.printStackTrace();
			}
		}

	}

	static class Unicorn extends Thread {
		int id;

		public Unicorn(int i) {
			id = i;
		}

		public void run() {
			for (int i = 0; i < k; i++) { // k meals for every unicorn
				try {
					play();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				try {
					eat();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

		public void play() throws InterruptedException {
			System.out.println("Child Unicorn " + id
					+ " is now attempting to play..\n\n");
			ui.output.append("Child Unicorn " + id
					+ " is now attempting to play..\n\n");
			long playTime = Br.play();
			System.out.println("Child Unicorn " + id + " is now playing.."
					+ " " + playTime + "\n\n");
			ui.output.append("Child Unicorn " + id + " is now playing.." + " "
					+ playTime + "\n\n");
			sleep(playTime);
		}

		public void eat() throws InterruptedException {
			in.down();
			mutex.down();
			System.out
					.println(id + " is hungry and now attempting to eat\n\n");
			ui.output.append(id + " is hungry and now attempting to eat\n\n");
			if (eating == m) {
				System.out.println(id + " woke up mother\n\n");
				ui.output.append(id + " woke up mother\n\n");
				for (int i = 0; i < m; i++)
					eating--;
				mother.up();
				mutex.up();
				notifier.down();
			} else
				mutex.up();
			System.out.println("Child Unicorn " + id + " is now eating..\n\n");
			ui.output.append("Child Unicorn " + id + " is now eating..\n\n");
			sleep((long) (Math.random() * 10000));
			mutex.down();
			eating++;
			if (eating == m) {
				System.out.println("All pots are now empty...\n\n");
				ui.output.append("All pots are now empty...\n\n");
				in.up();
			}
			mutex.up();
		}
	}

	static class Mother extends Thread {
		public void run() {
			for (int i = 0; i < Math.ceil(total * k * 1.0 / m); i++) {
				mother.down();
				System.out.println("Mother Unicorn is now filling pots...\n\n");
				ui.output.append("Mother Unicorn is now filling pots...\n\n");
				try {
					sleep((long) (Math.random() * 10000));
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println("All pots now are full....\n\n");
				ui.output.append("All pots now are full....\n\n");
				for (int j = 0; j < m - 1; j++) {
					in.up();
				}
				notifier.up();
				System.out.println("Mother Unicorn now go to sleep....\n\n");
				ui.output.append("Mother Unicorn now go to sleep....\n\n");
			}
		}
	}

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		m = sc.nextInt();
		k = sc.nextInt();
		total = 3 * n;
		eating = m;
		Mot.start();
		for (int i = 0; i < total; i++) {
			new Unicorn(i).start();
		}
	}

	public static void run(int nn, int mm, int kk) {
		n = nn;
		m = mm;
		k = kk;
		total = 3 * n;
		eating = m;
		Mot.start();
		for (int i = 0; i < total; i++) {
			new Unicorn(i).start();
		}
	}
}
